asynchroni volani udalosti z COM objektu (Automation objektu)

Otázka od: Karel Kimes

18. 9. 2002 12:07

ahoj,
- mam vytvoreny COM objekt (Automation objekt) TTest s podporou pro volani
udalosti
- objekt ma metodu Go
- tato metoda VYTVORI novou instanci vlakna (potomek TThread) a teto
instanci je v v jehoz metode execute se, z duvodu testu, ceka 5s a potom
se vyvola udalost OnEvent

ALE ono to NEFUNGUJE! Je to proto, ze tu udalost volam z jinyho vlakna? Jde
tady o chybu, z duvodu, ze udalost volam z jinyho apartmentu?


Jde mne o toto: zavolat metodu COM objektu, ktera v COM objektu spusti
nejaky asynchroni algoritmus a IHNED se vrati. Jakmile asynchroni alg.
napr. vypocita vysledek, chcu se o tom dozvedet, tzn. vyvolat udalost pro
klienta. Tak jak to delam ted to nefunguje.


castecna implementace kodu, avsak pro nastineni situace dostacujici:


   TTestThread = class(TThread) // **** moje testovaci vlakno
   private
     FEvents : ITestEvents;
   protected
     procedure Execute; override;
   public
     constructor Create(Events : ITestEvents);
   end;

   TTest = class(TAutoObject, IConnectionPointContainer, ITest)
   private
     { Private declarations }
     FConnectionPoints: TConnectionPoints;
     FConnectionPoint: TConnectionPoint;
     FEvents: ITestEvents;
     { note: FEvents maintains a *single* event sink. For access to more
       than one event sink, use FConnectionPoint.SinkList, and iterate
       through the list of sinks. }
   public
     procedure Initialize; override;
   protected
     { Protected declarations }
     property ConnectionPoints: TConnectionPoints read FConnectionPoints
       implements IConnectionPointContainer;
     procedure EventSinkChanged(const EventSink: IUnknown); override;
     procedure Go; safecall; // **** TOTO je moje metoda - osatatni casti
tohotobjektu vytvoril Wizard (DAX)
   end;


implementation


constructor TTestThread.Create(Events : ITestEvents);
begin
   inherited Create(true);

   FreeOnTerminate := true;
   FEvents := Events;
   Resume;
end;

procedure TTestThread.Execute;
begin
   Sleep(5000); // vlakno ceka 5s
   FEvents.OnEvent; // a potom vola udalost OnEvent (ktera je
implementovana v klintovi) - ALE ONO TO NEJEDE  
end;



procedure TTest.Go;
begin
   TTestThread.Create(FEvents); // spustim vlakno a IHNED se vratim
end;



kchodl

WinXP, D6PRO UPDATE PACK 2

Odpovedá: Malecek Ondrej

18. 9. 2002 12:38

Ahoj,
krome predavani instanci COM objektu mezi procesy se mezi thready musi vzdy
marshalovat. K plne spokojenosti pouzivam helpery:

CoMarshalInterThreadInterfaceInStream
a
CoGetInterfaceAndReleaseStream

O  

> -----Původní zpráva-----
> ahoj,
> - mam vytvoreny COM objekt (Automation objekt) TTest s podporou
> pro volani
> udalosti
> - objekt ma metodu Go
> - tato metoda VYTVORI novou instanci vlakna (potomek TThread) a teto
> instanci je v v jehoz metode execute se, z duvodu testu, ceka 5s a potom
> se vyvola udalost OnEvent
>
> ALE ono to NEFUNGUJE! Je to proto, ze tu udalost volam z jinyho
> vlakna? Jde
> tady o chybu, z duvodu, ze udalost volam z jinyho apartmentu?
>
>
> Jde mne o toto: zavolat metodu COM objektu, ktera v COM objektu spusti
> nejaky asynchroni algoritmus a IHNED se vrati. Jakmile asynchroni alg.
> napr. vypocita vysledek, chcu se o tom dozvedet, tzn. vyvolat udalost pro
> klienta. Tak jak to delam ted to nefunguje.